package summary;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;
import java.util.Vector;

public class Reader {
	
	public static enum ReadFormat{
		SIMULATION_DATA,
		EXPERIMENTAL_DATA,
		LONG_EXPERIMENTAL_DATA, 
		EGTSP_EXPERIMENTAL_DATA
	}
	
	BufferedReader in = null;
	Vector<InstantData> instants = new Vector<InstantData>();

	public Reader(String file,ReadFormat format){
		try {
			readFile(file,format);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}		
	}
	
	public Reader(String file,ReadFormat format,long start,long end){
		try {
			readFile(file,format,start,end);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}		
	}
	
	private void readFile(String file,ReadFormat format) throws FileNotFoundException {
		in = new BufferedReader(new FileReader(new File(file)));
		
		if(format == ReadFormat.SIMULATION_DATA)
			readMatrix();
		else if(format == ReadFormat.EXPERIMENTAL_DATA)
			readExperimentalData();
		else if(format == ReadFormat.LONG_EXPERIMENTAL_DATA)
			readExperimentalLongData();
		else if(format == ReadFormat.EGTSP_EXPERIMENTAL_DATA){
			readExperimentalEgtspData();
		}
	}
	
	private void readFile(String file,ReadFormat format,long start,long end) throws FileNotFoundException {
		in = new BufferedReader(new FileReader(new File(file)));
		
		if(format == ReadFormat.SIMULATION_DATA)
			readMatrix(start,end);
	}

	private void readMatrix(){
		String line = null;
		
		long second,id,clock,skew=0;
		
		InstantData instantData = null; 
		
		try {
			while ((line = in.readLine())!=null){				
				StringTokenizer tokenizer = new StringTokenizer(line," :[]=x");
				
				while(tokenizer.hasMoreElements()){
					String s = tokenizer.nextToken();
					second = Long.valueOf(s, 10);
					
					s = tokenizer.nextToken();
					id = Long.valueOf(s, 10);
					
					s = tokenizer.nextToken();
					clock = Long.valueOf(s, 10);
				
					s = tokenizer.nextToken();
					skew = Long.valueOf(s, 10);					

					if(id == 1){
						
						if(instantData != null){
							instants.add(instantData);
						}	
						
						instantData = new InstantData(second);
					}
					
					NodeData data = new NodeData(id,clock,skew);
					instantData.addNodeData(data);												
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void readMatrix(long start, long end){
		String line = null;
		
		long second,id,clock,skew=0;
		
		InstantData instantData = null; 
		
		try {
			while ((line = in.readLine())!=null){				
				StringTokenizer tokenizer = new StringTokenizer(line," :[]=x");
				
				while(tokenizer.hasMoreElements()){
					String s = tokenizer.nextToken();
					second = Long.valueOf(s, 10);
					
					s = tokenizer.nextToken();
					id = Long.valueOf(s, 10);
					
					s = tokenizer.nextToken();
					clock = Long.valueOf(s, 10);
				
					s = tokenizer.nextToken();
					skew = Long.valueOf(s, 10);	
					
					if(second < start || second > end)
						continue;

					if(id == 1){
						
						if(instantData != null){
							instants.add(instantData);
						}	
						
						instantData = new InstantData(second);
					}
					
					NodeData data = new NodeData(id,clock,skew);
					instantData.addNodeData(data);												
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	
	private void readExperimentalData(){
		String line = null;
		
		long id,clock,skew,_clock,_skew,__clock,__skew,___clock,___skew,____clock;
		
		InstantData instantData = null; 
		
		try {
			while ((line = in.readLine())!=null){				
				StringTokenizer tokenizer = new StringTokenizer(line," :[]=x");
				
				while(tokenizer.hasMoreElements()){
					String s = tokenizer.nextToken();
					
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					id = Long.valueOf(s, 16);
					
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					clock = Long.valueOf(s, 16);
					
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();				
					s = tokenizer.nextToken();
					skew = Long.valueOf(s, 16);
					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					_clock = Long.valueOf(s, 16);
//					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();				
//					s = tokenizer.nextToken();
//					_skew = Long.valueOf(s, 16);
//					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					__clock = Long.valueOf(s, 16);
//					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();				
//					s = tokenizer.nextToken();
//					__skew = Long.valueOf(s, 16);
//					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					___clock = Long.valueOf(s, 16);
//					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();				
//					s = tokenizer.nextToken();
//					___skew = Long.valueOf(s, 16);
//										
//					// synced
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();				
//					s = tokenizer.nextToken();
					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					id = Long.valueOf(s, 16);
//					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					clock = Long.valueOf(s, 16);
//										
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					_clock = Long.valueOf(s, 16);
//									
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					__clock = Long.valueOf(s, 16);
//									
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					___clock = Long.valueOf(s, 16);
//					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();				
//					s = tokenizer.nextToken();
//					skew = Long.valueOf(s, 16);
//					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();				
//					s = tokenizer.nextToken();
//					_skew = Long.valueOf(s, 16);
//					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();				
//					s = tokenizer.nextToken();
//					__skew = Long.valueOf(s, 16);
//					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();				
//					s = tokenizer.nextToken();
//					___skew = Long.valueOf(s, 16);
//										
//					// synced
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();				
//					s = tokenizer.nextToken();

					
					if(id == 0){
						if(instantData != null){
							instants.add(instantData);
						}						
						instantData = new InstantData(clock);
					}
					else{					
						NodeData data = new NodeData(id,clock,skew);
//						NodeData data = new NodeData(id,_clock,_skew);
//						NodeData data = new NodeData(id,__clock,__skew);
//						NodeData data = new NodeData(id,___clock,___skew);
						instantData.addNodeData(data);
					}
					
					
//				while(tokenizer.hasMoreElements()){
//					String s = tokenizer.nextToken();
//					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					id = Long.valueOf(s, 16);
//					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					clock = Long.valueOf(s, 16);
//					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();				
//					s = tokenizer.nextToken();
//					skew = Long.valueOf(s, 16);
//					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();
//					_clock = Long.valueOf(s, 16);
//					
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();				
//					s = tokenizer.nextToken();
//					_skew = Long.valueOf(s, 16);
//															
//					s = tokenizer.nextToken();
//					s = tokenizer.nextToken();				
//					s = tokenizer.nextToken();
//					
//					if(id == 0){
//						if(instantData != null){
//							instants.add(instantData);
//						}						
//						instantData = new InstantData(clock);
//					}
//					else{					
////						NodeData data = new NodeData(id,clock,skew);
//						NodeData data = new NodeData(id,_clock,_skew);
//						instantData.addNodeData(data);
//					}											

				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void readExperimentalLongData(){
		String line = null;
		
		long id,clock,skew=0;
		
		InstantData instantData = null; 
		
		try {
			while ((line = in.readLine())!=null){				
				StringTokenizer tokenizer = new StringTokenizer(line," :[]=x");
				
				while(tokenizer.hasMoreElements()){
					String s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					id = Long.valueOf(s, 16);
					
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					clock = Long.valueOf(s, 16);

					// local
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();				
					s = tokenizer.nextToken();
					skew = Long.valueOf(s, 16);
					
					// meanX
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					
					// meanY
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					
					// synced
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();

					if(id == 0){
						if(instantData != null){
							instants.add(instantData);
						}		
						instantData = new InstantData(clock);
					}
					else{					
						NodeData data = new NodeData(id,clock,skew);
						instantData.addNodeData(data);
					}											
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void readExperimentalEgtspData() {
		String line = null;
		
		long id,clock,gradient_clock,skew=0;
		
		InstantData instantData = null; 
		
		try {
			while ((line = in.readLine())!=null){				
				StringTokenizer tokenizer = new StringTokenizer(line," :[]=x");
				
				while(tokenizer.hasMoreElements()){
					String s = tokenizer.nextToken();
					
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					id = Long.valueOf(s, 16);
					
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					clock = Long.valueOf(s, 16);
					
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					gradient_clock = Long.valueOf(s, 16);
					
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();				
					s = tokenizer.nextToken();
					skew = Long.valueOf(s, 16);
					
					// synced
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();
					s = tokenizer.nextToken();

					if(id == 0){
						if(instantData != null){
							instants.add(instantData);
						}		
						instantData = new InstantData(clock);
					}
					else{					
						NodeData data = new NodeData(id,clock,skew);
//						NodeData data = new NodeData(id,gradient_clock,skew);
						instantData.addNodeData(data);
					}											
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

	
	public Vector<InstantData> getMatrix(){
		return instants;	
	}
}
